using System;
using NUnit.Framework;
using OpenRay;

namespace Tests
{
	[TestFixture]
	public class TestMatrix
	{
		[Test]
		public void TestEquals()
		{
			Matrix m = Matrix.Identity;
			Matrix b = new Matrix( 1f, 0f, 0f, 0f,
			                       0f, 1f, 0f, 0f,
			                       0f, 0f, 1f, 0f,
			                       0f, 0f, 0f, 1f );
			
			Assert.AreEqual(b, m);
		}
		
		[Test]
		public void TestMultiply() 
		{
			Matrix m = Matrix.Identity;
			Matrix t = Matrix.CreateTranslate( 2f, 3f, 4f );
			
			Assert.AreEqual( t, m * t );
			
			Matrix a = new Matrix(  1,  2,  3,  4,
			                        5,  6,  7,  8,
			                        9, 10, 11, 12,
			                       13, 14, 15, 16 );
			
			Matrix b = new Matrix( 1,  5,  3,  4,
			                       2,  6,  7,  8,
			                       3, 10, 11, 12,
			                       4, 14, 15, 16 );
			
			Matrix result = new Matrix(  30, 103, 110, 120,
			                             70, 243, 254, 280,
			                            110, 383, 398, 440,
			                            150, 523, 542, 600 );
			
			Assert.AreEqual( result, a * b );
		}
		
		[Test]
		public void TestInvert()
		{
			Matrix m = Matrix.CreateTranslate( 1, 2, 3 );
			Matrix im = Matrix.CreateTranslate( -1, -2, -3 );
			
			Assert.AreEqual( im, Matrix.Inverse( m ) );
		}
		
		[Test]
		public void TestMultiplyPoint()
		{
			Matrix m = Matrix.CreateTranslate( 1, 2, 3 );
			Point p = new Point(0, 0, 0, 1);
			
			Assert.AreEqual( new Point(1, 2, 3, 1), m * p );
		}
		
		[Test]
		public void TestMultiplyVector()
		{
			Matrix m = Matrix.CreateTranslate( 1, 2, 3 );
			Vector v = new Vector(0, 0, 1);
			
			Assert.AreEqual( v, m * v );
		}
		
		[Test]
		public void TestTransposedMultiply()
		{
			Matrix m = new Matrix( 1, 2, 3, 4,
			                       4, 2, 3, 6,
			                       2, 2, 1, 4,
			                       2, 9, 6, 4 );
			
			Vector v = new Vector(1, 3, 4);
			
			Assert.AreEqual( new Vector(21, 16, 16), Matrix.TransposedMultiply(m, v) );
		}
	}
}

